package com.mcxx.modules.filemanage.easypoi.util;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.mcxx.modules.filemanage.easypoi.handler.IExcelDictHandlerImpl;
import com.yinhai.ta404.component.audit.annotation.Condition;
import com.yinhai.ta404.component.audit.common.ConditionTypeEnum;
import com.yinhai.ta404.component.audit.vo.ExcelInfo;
import com.yinhai.ta404.core.event.EventPublish;
import com.yinhai.ta404.core.exception.AppException;
import com.yinhai.ta404.core.utils.ValidateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class ExportExcelService {

    @Resource
    private EventPublish eventPublish;


    public ExcelInfo exportOrgOpLogs(Class clazz,List list,
                                     String excelName, String titleName, String shellName,Boolean target,String... hihdCloum) {




        if(null != hihdCloum && hihdCloum.length > 0){
            hihdColumn(target,clazz,hihdCloum);
        }

        ExportParams exportParams = new ExportParams(titleName, shellName);
        exportParams.setType(ExcelType.HSSF);
        exportParams.setDictHandler(new IExcelDictHandlerImpl());
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, clazz,list);
        byte[] bytes = this.workBookByteArray(workbook);
        Map<String, Object> conditions = this.getConditions(list);
        ExcelInfo excelInfo = new ExcelInfo(excelName, bytes);
        excelInfo.setConditions(conditions);
        excelInfo.setAuditType("4");
        eventPublish.publish(excelInfo, "audit_record_event");
        if(null != hihdCloum && hihdCloum.length > 0){
            hihdColumn(true,clazz,hihdCloum);
        }
        return excelInfo;
    }


    public Workbook exportWorkBook(Class clazz,List list,String titleName, String shellName,Boolean target) {
        ExportParams exportParams = new ExportParams(titleName, shellName);
        exportParams.setType(ExcelType.HSSF);
        exportParams.setDictHandler(new IExcelDictHandlerImpl());
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, clazz,list);
        return workbook;
    }

    public ExcelInfo exportExcelByWorkBook(Workbook workbook,List list, String excelName) {
        byte[] bytes = this.workBookByteArray(workbook);
        Map<String, Object> conditions = this.getConditions(list);
        ExcelInfo excelInfo = new ExcelInfo(excelName, bytes);
        excelInfo.setConditions(conditions);
        excelInfo.setAuditType("4");
        eventPublish.publish(excelInfo, "audit_record_event");
        return excelInfo;
    }

    public ExcelInfo exportExcelByWorkBook(Workbook workbook,String excelName,Object object){
        byte[] bytes = this.workBookByteArray(workbook);
        ExcelInfo excelInfo = new ExcelInfo(excelName, bytes);
        Map<String, Object> conditions = this.getConditions(object);
        excelInfo.setAuditType("4");
        excelInfo.setConditions(conditions);
        eventPublish.publish(excelInfo, "audit_record_event");
        return excelInfo;
    }
    public byte[] exportByteByWorkbook(Workbook workbook){
        return this.workBookByteArray(workbook);
    }

    public void hihdColumn(Boolean target,Class claes, String... columnName) {
        try{
            if (target == null) {
                target = true;
            }

            for(String s : columnName){
                if(StringUtils.isBlank(s)){
                    continue;
                }
                Field field = claes.getDeclaredField(s);

                Excel excelAnnon = field.getAnnotation(Excel.class);

                InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelAnnon);
                Field excelField = invocationHandler.getClass().getDeclaredField("memberValues");
                excelField.setAccessible(true);
                Map memberValues = (Map) excelField.get(invocationHandler);
                memberValues.put("isColumnHidden", target);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    protected Map<String, Object> getConditions(Object obj) {
        Map<String, Object> conditions = new HashMap(8);
        Class<?> aClass = obj.getClass();
        Arrays.stream(aClass.getDeclaredFields()).forEach((filed) -> {
            if (filed.isAnnotationPresent(Condition.class)) {
                Object value = null;

                try {
                    filed.setAccessible(true);
                    value = filed.get(obj);
                } catch (IllegalAccessException var6) {
                    var6.printStackTrace();
                }

                if (ValidateUtil.isEmpty(value)) {
                    return;
                }

                Condition condition = (Condition)filed.getAnnotation(Condition.class);
                if (condition.type() == ConditionTypeEnum.DATE && value instanceof Date) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    value = sdf.format(value);
                }

                conditions.put(condition.name(), value);
            }

        });
        return conditions;
    }
    protected byte[] workBookByteArray(Workbook workbook) {
        try {
            ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
            Throwable var3 = null;

            byte[] var4;
            try {
                workbook.write(byteOutputStream);
                var4 = byteOutputStream.toByteArray();
            } catch (Throwable var14) {
                var3 = var14;
                throw var14;
            } finally {
                if (byteOutputStream != null) {
                    if (var3 != null) {
                        try {
                            byteOutputStream.close();
                        } catch (Throwable var13) {
                            var3.addSuppressed(var13);
                        }
                    } else {
                        byteOutputStream.close();
                    }
                }

            }

            return var4;
        } catch (IOException var16) {
            throw new AppException("导出失败");
        }
    }
}
